#ifndef serial_h
#define serial_h
#include <ModbusMaster.h>
#include "pins.h"
#include "logger.h"

// 初始化Modbus主站
ModbusMaster node1;
ModbusMaster node2;

void print_logo();

// 初始化串口,Serial1用于Modbus通信，Serial用于调试输出
void setup_serial()
{
  Serial.begin(115200);
  Serial1.begin(9600, SERIAL_8E1); // RX, TX为pins.h定义的引脚
  node1.begin(1, Serial1);         // 1为Motor地址
  node2.begin(2, Serial1);         // 1为CO2泵地址
  print_logo();
}

// 设置电机转速（0x06写寄存器0x0042为-1000-1000）
bool setMotorSpeed(uint16_t value)
{
  uint8_t result = node1.writeSingleRegister(0x0042, value);
  // Serial.print("Modbus writeSingleRegister result: ");
  // Serial.println(result);
  return result == node1.ku8MBSuccess;
}

// 设置CO2泵最大压力（0x06写寄存器0x0002为0-4200）
bool setMaxPres(uint16_t value)
{
  uint8_t result = node2.writeSingleRegister(0x0002, value);
  // Serial.print("Modbus writeSingleRegister result: ");
  // Serial.println(result);
  return result == node2.ku8MBSuccess;
}

// 设置CO2泵最小压力（0x06写寄存器0x0003为0-4200）
bool setMinPres(uint16_t value)
{
  uint8_t result = node2.writeSingleRegister(0x0003, value);
  // Serial.print("Modbus writeSingleRegister result: ");
  // Serial.println(result);
  return result == node2.ku8MBSuccess;
}

// 设置CO2泵压力清零（0x05写线圈0x0003为0xFF00）
bool clearPres()
{
  uint8_t result = node2.writeSingleCoil(0x0003,0);
  // Serial.print("Modbus writeSingleRegister result: ");
  // Serial.println(result);
  return result == node2.ku8MBSuccess;
}

// 获取CO2泵最大压力(0x03读保持寄存器0x0002，0-4200)
bool getMaxPres()
{
  uint8_t result = node2.readHoldingRegisters(0x0002, 1);
  if (result == node2.ku8MBSuccess)
  {
    uint16_t maxPres = node2.getResponseBuffer(0); // 读取到的值
    logf("MaxPres %d ", maxPres);
    return true;
  }
  else
  {
    logf("Error %d", result);
    return false;
  }
}

// 获取CO2泵最小压力(0x03读保持寄存器0x0003，0-4200)
bool getMinPres()
{
  uint8_t result = node2.readHoldingRegisters(0x0003, 1);
  if (result == node2.ku8MBSuccess)
  {
    uint16_t minPres = node2.getResponseBuffer(0); // 读取到的值
    logf("MinPres %d ", minPres);
    return true;
  }
  else
  {
    logf("Error %d", result);
    return false;
  }
}

// 设置CO2泵流量（0x06写寄存器0x0004为1-9999）
bool setTraffic(uint16_t value)
{
  uint8_t result = node2.writeSingleRegister(0x0004, value);
  // Serial.print("Modbus writeSingleRegister result: ");
  // Serial.println(result);
  return result == node2.ku8MBSuccess;
}

// 获取CO2泵流量(0x03读保持寄存器0x0004，1-9999)
bool getTraffic()
{
  uint8_t result = node2.readHoldingRegisters(0x0004, 1);
  if (result == node2.ku8MBSuccess)
  {
    uint16_t traffic = node2.getResponseBuffer(0); // 读取到的值
    logf("traffic %d ", traffic);
    return true;
  }
  else
  {
    logf("Error %d", result);
    return false;
  }
}

// 启动CO2泵（0x05写线圈0x0001为0xFF00）
bool startPump()
{
  uint8_t result = node2.writeSingleCoil(0x0001, 1);
  // Serial.print("Modbus writeSingleCoil result: ");
  // Serial.println(result);
  return result == node2.ku8MBSuccess;
}

// 停止CO2泵（0x05写线圈0x0001为0x0000）
bool stopPump()
{
  uint8_t result = node2.writeSingleCoil(0x0001, 0);
  // Serial.print("Modbus writeSingleCoil result: ");
  // Serial.println(result);
  return result == node2.ku8MBSuccess;
}

// 读取CO2泵状态（0x01读线圈0x0001, 0/1）
bool getPumpState()
{
  uint8_t result = node2.readCoils(0x0001, 1);
  if (result == node2.ku8MBSuccess)
  {
    uint8_t pumpState = node2.getResponseBuffer(0); // 0=OFF, 1=ON
    logf("pumpState %d ", pumpState);
    return true;
  }
  else
  {
    logf("Error %d", result);
    return false;
  }
}

// 读取CO2泵压力（0x03读保持寄存器0x0005，1-4200）
bool getPres()
{
  uint8_t result = node2.readHoldingRegisters(0x0005, 1);
  if (result == node2.ku8MBSuccess)
  {
    uint16_t pres = node2.getResponseBuffer(0); // 读取到的值
    logf("pres %d ", pres);
    return true;
  }
  else
  {
    logf("Error %d", result);
    return false;
  }
}

// 开启CO2泵压力采样（0x06写保持寄存器0x0006为0-100）采样间隔为value*50ms
bool startPresSample(uint16_t value)
{
  uint8_t result = node2.writeSingleRegister(0x0006, value);
  // Serial.print("Modbus writeSingleRegister result: ");
  // Serial.println(result);
  return result == node2.ku8MBSuccess;
}

// 定义命令-函数映射结构体
typedef bool (*FuncWithArg)(uint16_t);
typedef bool (*FuncNoArg)();

struct CmdMap
{
  const char *name;
  FuncWithArg funcWithArg;
  FuncNoArg funcNoArg;
  bool needArg;
};

// 映射表
const CmdMap cmdTable[] = {
    {"setMaxPres", setMaxPres, nullptr, true},
    {"setMinPres", setMinPres, nullptr, true},
    {"setTraffic", setTraffic, nullptr, true},
    {"startPresSample", startPresSample, nullptr, true},
    {"clearPres", nullptr, clearPres, false},
    {"getMaxPres", nullptr, getMaxPres, false},
    {"getMinPres", nullptr, getMinPres, false},
    {"getTraffic", nullptr, getTraffic, false},
    {"startPump", nullptr, startPump, false},
    {"stopPump", nullptr, stopPump, false},
    {"pumpState", nullptr, getPumpState, false},
    {"getPres", nullptr, getPres, false},
};
const int cmdCount = sizeof(cmdTable) / sizeof(cmdTable[0]);

void print_logo() {
    Serial.print("\033[31m");
    Serial.println("       .__                            ");
    Serial.println("  _____|__|___.__.__ _______    ____  ");
    Serial.println(" /  ___/  <   |  |  |  \\__  \\  /    \\ ");
    Serial.println(" \\___ \\|  |\\___  |  |  // __ \\|   |  \\");
    Serial.println("/____  >__|/ ____|____/(____  /___|  /");
    Serial.println("     \\/    \\/               \\/     \\/ ");
    Serial.print("\033[0m");
}

#endif